package org.finesys.ai.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.finesys.ai.entity.AigcDoc;
import org.finesys.ai.entity.AigcEmbedStore;
import org.finesys.ai.entity.AigcKnowledge;
import org.finesys.ai.entity.AigcModel;
import org.finesys.ai.mapper.AigcKnowledgeMapper;
import org.finesys.ai.service.AigcDocService;
import org.finesys.ai.service.AigcEmbedStoreService;
import org.finesys.ai.service.AigcKnowledgeService;
import org.finesys.ai.service.AigcModelService;
import org.finesys.chat.core.base.constants.EventTypeEnum;
import org.finesys.chat.core.base.events.KnowledgeStoreEvent;
import org.finesys.common.core.util.SpringContextHolder;
import org.finesys.common.mp.core.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@RequiredArgsConstructor
@Slf4j
public class AigcKnowledgeSericeImpl extends BaseServiceImpl<AigcKnowledgeMapper, AigcKnowledge> implements AigcKnowledgeService {


    private final AigcModelService aigcModelService;
    private final AigcEmbedStoreService aigcEmbedStoreService;
    private final AigcDocService aigcDocService;


    @Override
    public boolean saveKnowledge(AigcKnowledge knowledge) {
        this.save(knowledge);
        //发送事件
        sendEvent(knowledge, EventTypeEnum.ADD.getName());
        return Boolean.TRUE;
    }


    @Override
    public boolean updateKnowledge(AigcKnowledge knowledge) {
        this.updateById(knowledge);
        //发送事件
        sendEvent(knowledge, EventTypeEnum.UPDATE.getName());
        return Boolean.TRUE;
    }

    @Override
    public AigcKnowledge getKnowledgeById(String id) {
        AigcKnowledge knowledge = this.getById(id);
        build(knowledge);
        return knowledge;
    }

    /**
     * 构建知识库信息
     */
    private AigcKnowledge build(AigcKnowledge knowledge) {
        if (knowledge != null) {
            if (StringUtils.hasText(knowledge.getEmbedModelId())) {
                knowledge.setEmbedModel(aigcModelService.getById(knowledge.getEmbedModelId()));
            }
            if (StringUtils.hasText(knowledge.getEmbedStoreId())) {
                knowledge.setEmbedStore(aigcEmbedStoreService.getById(knowledge.getEmbedStoreId()));
            }

            List<AigcDoc> aigcDocList = aigcDocService.findByKnowledgeId(knowledge.getId());
            if (aigcDocList != null && aigcDocList.size() > 0) {
                knowledge.setDocs(aigcDocList);
                knowledge.setDocsNum(aigcDocList.size());
                knowledge.setTotalSize(aigcDocList.stream().filter(d -> d.getFileSize() != null).mapToLong(AigcDoc::getFileSize).sum());
            }
        }
        return knowledge;
    }

    /**
     * 构建知识库信息
     */
    public List<AigcKnowledge> build(List<AigcKnowledge> knowledgeList) {
        //空数据直接返回
        if (knowledgeList == null || knowledgeList.size() == 0) {
            return knowledgeList;
        }
        //获取模型信息
        Map<String, AigcModel> modelMap = aigcModelService.list().stream().collect(Collectors.toMap(AigcModel::getId, a -> a, (k1, k2) -> k1));
        //获取存储信息
        Map<String, AigcEmbedStore> embedStoreMap = aigcEmbedStoreService.list().stream().collect(Collectors.toMap(AigcEmbedStore::getId, a -> a, (k1, k2) -> k1));
        //获取文档信息
        Map<String, List<AigcDoc>> docMap = aigcDocService.list(Wrappers.lambdaQuery()).stream().collect(Collectors.groupingBy(AigcDoc::getKnowledgeId));
        //处理知识库信息
        knowledgeList.forEach(knowledge -> {
            if (StringUtils.hasText(knowledge.getEmbedModelId())) {
                AigcModel aigcModel = modelMap.get(knowledge.getEmbedModelId());
                if (null != aigcModel) {
                    knowledge.setEmbedModel(aigcModel);
                }
            }
            if (StringUtils.hasText(knowledge.getEmbedStoreId())) {
                AigcEmbedStore embedStore = embedStoreMap.get(knowledge.getEmbedStoreId());
                if (null != embedStore) {
                    knowledge.setEmbedStore(embedStore);
                }
            }
            List<AigcDoc> aigcDocList = docMap.get(knowledge.getId());
            if (aigcDocList != null && aigcDocList.size() > 0) {
                knowledge.setDocs(aigcDocList);
                knowledge.setDocsNum(aigcDocList.size());
                knowledge.setTotalSize(aigcDocList.stream().filter(d -> d.getFileSize() != null).mapToLong(AigcDoc::getFileSize).sum());
            }
        });
        return knowledgeList;
    }

    @Override
    public boolean deleteKnowledge(String[] ids) {
        if (ids == null || ids.length == 0) {
            return false;
        }
        //获取文档信息
        List<AigcKnowledge> aigcKnowledgeList = this.list(Wrappers.<AigcKnowledge>lambdaQuery().in(AigcKnowledge::getId, Arrays.stream(ids).toArray()));
        //删除文档信息
        aigcKnowledgeList.forEach(knowledge -> {
            //删除知识库
            this.removeById(knowledge.getId());
            //发送事件
            sendEvent(knowledge, EventTypeEnum.DELETE.getName());
        });
        return true;
    }

    /**
     * 向知识库中发送事件
     *
     * @param knowledge 知识对象
     * @param type      事件类型
     */
    private void sendEvent(AigcKnowledge knowledge, String type) {
        KnowledgeStoreEvent knowledgeStoreEvent = new KnowledgeStoreEvent(knowledge, type);
        boolean send = SpringContextHolder.publishEvent(knowledgeStoreEvent);
        if (!send) {
            if (log.isWarnEnabled()) {
                log.warn(String.format("发送知识库[%s]事件失败", knowledgeStoreEvent));
            }
        }
    }
}
